/* Shift-JIS */
/* UTF-8 */
/********************************************************************************/
/*ソース名:                                                                     */
/*　　table.c                                                              */
/*機能:                                                                         */
/*　　TODO:ファイルの機能を書く                    　　　　　　　　　　　　　　 */
/*作成者:                                                                       */
/*　　2010-9-16 guanxiaoying（CBS）                                                 */
/********************************************************************************/
/*変更履歴:                                                                     */
/*　2010-9-16　guanxiaoying　　新規作成                                                */
/********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "typedef.h"
#include "Id.h"
#include "lib_func.h"
#include "core.h"
#include "encode.h"
#include "../inc/core_internal.h"
#include "./textfile/pf_file.h"
#include "./memory/mem_interface.h"
#include "../alert/alert.h"
#include "./table.h"
#include "./core_table.h"
#include "./trace_ast_table.h"
#include "./trace_cmd_table.h"
#include "../parser/coredef.h"
#define GET_OFFSET_ADDR( man, idx, sub_idx )  ((char*)man->memoryBlocks[idx] + ( sub_idx )* man->con_usSize)


MEMORY_ERROR_INFO   stErrorCode = {
		NULL, 0, 0, 0
};
S4  Result = COEXIT_SUCCESS;
static BOOL RegisterBuf( TABLEMANAGER *man )
{
	U4 u4Idx = 0;
	if( man->u4Idx )
	{
		return 1;
	}
	u4Idx = MemRegisiter( man->con_pszName );
	if( u4Idx == 0 )
	{
		// MemRegisiter is not necessary, it's a optional process
		u4Idx = 1;
	}
	if( man->con_usSize == 0 ){
		return 0;
	}
	man->u4Idx = u4Idx;
	man->maxRecordNum = 0;
	man->block_num = 0;
	man->astMaxNum_LastPage = (AST)0;
	man->astTabNum_LastPage = (AST)0;
	man->astMaxNum_Block = MemGetBlockSize();
	return 1;
}
static BOOL RegisterTbl(  TABLEMANAGER *man  )
{
	U4 u4Idx;
	if( man->u4Idx )
	{
		return 1;
	}
	u4Idx = MemRegisiter( man->con_pszName );
	if( u4Idx == 0 )
	{
		u4Idx = 1;
	}
	if( man->con_usSize == 0 ){
		return 0;
	}
	man->u4Idx = u4Idx;
	man->maxRecordNum = 0;
	man->block_num = 0;
	man->astMaxNum_LastPage = (AST)0;
	man->astTabNum_LastPage = (AST)0;
	man->astMaxNum_Block = MemGetBlockSize()/man->con_usSize;
	return( 1 );
}
static void setOwnerId_LastPage( U4 idx, U2 no, buffer_owner_info * p_owner, VOID (*resetListener)( U4  procid, U2 index ) )
{
	if( p_owner != NULL )
	{
		p_owner->index = no+1;
		p_owner->procid = idx;
		p_owner->resetListener = resetListener ;
	}
}
VOID* Check_Com( TABLEMANAGER *man, VOID (*resetListener)( U4  procid, U2 index ), AST index )
{
	buffer_owner_info  * p_owner = NULL;
	if( man->u4Idx == 0  )
	{
		return NULL;
	}
	if( index <= 0 )
	{
		return NULL;
	}
	if( index > man->maxRecordNum )
	{
		Throw_MemoryError( man, INDEX_TOOLARGER, man->maxRecordNum, index );
		return NULL;
	}
	if( man->astMaxNum_Block == 0 )
	{
		man->astMaxNum_Block = MemGetBlockSize( )/man->con_usSize;
	}
	if( man->memoryBlocks[index/man->astMaxNum_Block] == NULL  )
	{
		man->memoryBlocks[index/man->astMaxNum_Block] = MemTblSwapInTable( man->u4Idx, index/man->astMaxNum_Block, &p_owner );
		if( man->memoryBlocks[index/man->astMaxNum_Block] == NULL )
		{
			Throw_MemoryError( man, ALLOC_SWAPOUT_DATALOST, man->u4Idx, index/man->astMaxNum_Block );
			return (FALSE);
		}
		setOwnerId_LastPage( man->u4Idx, index/man->astMaxNum_Block, p_owner, resetListener );
	}
	return man->memoryBlocks[index/man->astMaxNum_Block];
}
BOOL AllocBuffer_Com( TABLEMANAGER *bufMan, AST astReqArg, VOID (*resetListener)( U4  procid, U2 index ) )
{
	BOOL		ret;		/* 戻り値			*/
	VOID*		pStart;
	AST		astTotalReq;
	AST		astReq;
//	AST     astBlockNum;
	U4  ulReqSize;
	U4  blockSize = MemGetBlockSize();
	buffer_owner_info  * p_owner = NULL;
	buffer_owner_info owner;
	if ( bufMan == NULL ){
		return FALSE;
	}
	if( bufMan->u4Idx == 0 )
	{
		ret = RegisterBuf( bufMan );
		if( ret == FALSE )
		{
			return ret;
		}
	}
	/* astReqArg  をastTotalReq　に確保する */
	astTotalReq = astReqArg;
	if( astTotalReq > 0 && bufMan->maxRecordNum == 0 )
	{
		astTotalReq++;
	}
//	astBlockNum = bufMan->block_num;
	while( astTotalReq != 0 )
	{
		/*_____[ 領域確保要求 ]_________________________________________*/
		if( astTotalReq > (AST)0 )
		{
			if( bufMan->astTabNum_LastPage + astTotalReq <= bufMan->astMaxNum_LastPage )
			{
				bufMan->astTabNum_LastPage += astTotalReq;
				break;
			}
			{
				if( bufMan->astTabNum_LastPage + astTotalReq <= bufMan->astMaxNum_Block )
				{
					ulReqSize = blockSize;
					if( !bufMan->astMaxNum_LastPage )
					{
						ret = MemNewMemory( ulReqSize,(VOID**) &bufMan->memoryBlocks[bufMan->block_num], &p_owner );
						if( !ret )
						{
							Throw_MemoryError( bufMan, ALLOC_NEWMEMORY, bufMan->maxRecordNum, 0 );
							return (FALSE);
						}
					}
					bufMan->astTabNum_LastPage += astTotalReq;
					bufMan->astMaxNum_LastPage = MemGetPagesize(bufMan->memoryBlocks[bufMan->block_num])/bufMan->con_usSize;
					setOwnerId_LastPage( bufMan->u4Idx, bufMan->block_num, p_owner, resetListener );
					break;
				}
				/* オーバーフローチェック */
				if( bufMan->block_num >= MAX_VOLUMN_OF_TABLE )
				{
					Throw_MemoryError( bufMan, ALLOC_OVERFLOW, MAX_VOLUMN_OF_TABLE, bufMan->block_num );
					return (FALSE);
				}
				if( astTotalReq >= bufMan->astMaxNum_Block )
				{
					Throw_MemoryError( bufMan, ALLOC_BUFFER_TOOLONG, bufMan->astMaxNum_Block, astTotalReq );
					return (FALSE);
				}
				astReq = bufMan->astMaxNum_Block - bufMan->astTabNum_LastPage;
				bufMan->block_num++;

				ret = MemNewMemory( blockSize, (VOID**)&bufMan->memoryBlocks[bufMan->block_num], &p_owner );
				if( !ret  )
				{
					Throw_MemoryError( bufMan, ALLOC_NEWMEMORY, bufMan->maxRecordNum, 0 );
					return (FALSE);
				}
				setOwnerId_LastPage( bufMan->u4Idx, bufMan->block_num, p_owner, resetListener );
				bufMan->astTabNum_LastPage = astTotalReq;
				bufMan->astMaxNum_LastPage = MemGetPagesize(bufMan->memoryBlocks[bufMan->block_num])/bufMan->con_usSize;
				bufMan->maxRecordNum += astReq;
				break ;
			}
			continue;
		}
		/*_____[ 領域開放要求 ]_________________________________________*/
		else if( astTotalReq < (AST)0 )
		{
			/*  アンダーフローチェック */
			if( ( bufMan->maxRecordNum + astTotalReq ) < (AST)0 )
			{
				Throw_MemoryError( bufMan, ALLOC_UNDERFLOW, bufMan->maxRecordNum, astTotalReq );
				return (FALSE);
			}
			if( bufMan->block_num == 0 )
			{
				astReq = astTotalReq - 1;
			}
			else
			{
				astReq = astTotalReq;
			}
			if( bufMan->astTabNum_LastPage + astReq > 0 )
			{
				if( bufMan->memoryBlocks[bufMan->block_num] == NULL )
				{
					bufMan->memoryBlocks[bufMan->block_num] = MemTblSwapInTable( bufMan->u4Idx, bufMan->block_num, &p_owner );
					if( bufMan->memoryBlocks[bufMan->block_num] == NULL )
					{
						Throw_MemoryError( bufMan, ALLOC_SWAPOUT_DATALOST, bufMan->u4Idx, bufMan->block_num );
						return (FALSE);
					}
					setOwnerId_LastPage( bufMan->u4Idx, bufMan->block_num, p_owner, resetListener );
				}
				/* 現時点のメモリ塊はまだ使われる場合*/
				/* 解放の行数を計算（すべて、1回解放する)*/
				astReq = astTotalReq;
				astTotalReq = 0;
				bufMan->astTabNum_LastPage += astReq;
				/* 減った分のﾒﾓﾘにｺﾞﾐを入れる				*/
				pStart = (char*)bufMan->memoryBlocks[bufMan->block_num] + (size_t)( bufMan->con_usSize * ( bufMan->astTabNum_LastPage ) );
				if( pStart != NULL )
				{
					memset( pStart, 0x0, (size_t)( bufMan->con_usSize * (-astReq) ) );
				}
				break;
			}
			else
			{
				/* 現時点のメモリ塊は使われなくなる場合*/
				/* 解放の行数を計算*/
				if( bufMan->block_num > 0 )
				{
					astReq = -(bufMan->astTabNum_LastPage);
					astTotalReq -= astReq;
					ret = MemFreeMemory((VOID**)&bufMan->memoryBlocks[bufMan->block_num]);
					if( !ret )
					{
						Throw_MemoryError( bufMan, ALLOC_FREEMEMORY, bufMan->block_num, 0  );
						return (FALSE);
					}
					bufMan->memoryBlocks[bufMan->block_num] = NULL;

					/* 新しいメモリ塊を配って、中間ファイルからデータを読み込む*/
					/* 保持するメモリ塊の数から１を引く */
					(bufMan->block_num) --;
					bufMan->astTabNum_LastPage = bufMan->astMaxNum_Block;
					bufMan->astMaxNum_LastPage = bufMan->astMaxNum_Block;
					setOwnerId_LastPage( bufMan->u4Idx, bufMan->block_num, &owner , resetListener);
					if( !MemIsValidPage( bufMan->memoryBlocks[bufMan->block_num], &owner ) )
					{
						bufMan->memoryBlocks[bufMan->block_num] = MemTblSwapInTable( bufMan->u4Idx, bufMan->block_num, &p_owner );
						if( bufMan->memoryBlocks[bufMan->block_num] == NULL )
						{
							Throw_MemoryError( bufMan, ALLOC_SWAPOUT_DATALOST, bufMan->u4Idx, bufMan->block_num );
							return (FALSE);
						}
						setOwnerId_LastPage( bufMan->u4Idx, bufMan->block_num, p_owner, resetListener );
					}
				}
				else
				{
					astTotalReq = 0;
					pStart = (char*)bufMan->memoryBlocks[bufMan->block_num] ;
					memset( pStart, 0x0, (size_t)( bufMan->con_usSize * (bufMan->astTabNum_LastPage) ) );
					bufMan->astTabNum_LastPage = 0;
				}
			}
		}
	}
	/*該当するテーブルの行の総数を更新する*/
	bufMan->maxRecordNum += astReqArg;
	if( bufMan->ulMaxByte < bufMan->maxRecordNum )
	{
		bufMan->ulMaxByte = bufMan->maxRecordNum;
	}
	return( 1 );
}
BOOL AllocTable_Com( TABLEMANAGER *tblMan, AST astReqArg , VOID (*resetListener)( U4  procid, U2 index ))
{
	BOOL		ret;		/* 戻り値			*/
	VOID*		pStart;
	AST		astTotalReq;
	AST		astReq;
	AST     astBlockNum;
	U4  ulReqSize;
	U4  blockSize = MemGetBlockSize();
	buffer_owner_info  * p_owner = NULL;
	buffer_owner_info owner;

	if ( tblMan == NULL ){
		return FALSE;
	}
	if( tblMan->u4Idx == 0 )
	{
		ret = RegisterTbl( tblMan );
		if( ret == FALSE )
		{
			return ret;
		}
	}
	/* astReqArg  をastTotalReq　に確保する */
	astTotalReq = astReqArg;
	if( astTotalReq > 0 && tblMan->maxRecordNum == 0 )
	{
		astTotalReq++;
	}
	astBlockNum = tblMan->block_num;
	while( astTotalReq != 0 )
	{
		/*_____[ 領域確保要求 ]_________________________________________*/
		if( astTotalReq > (AST)0 )
		{
			if( tblMan->astTabNum_LastPage + astTotalReq <= tblMan->astMaxNum_LastPage )
			{
				tblMan->astTabNum_LastPage += astTotalReq;
				break;
			}
			/*  要求されたastReqArg分のメモリ領域は連続する必要がない */
			if( tblMan->astTabNum_LastPage + astTotalReq <= tblMan->astMaxNum_Block )
			{
				ulReqSize = (tblMan->astTabNum_LastPage + astTotalReq)*tblMan->con_usSize;
				if( tblMan->astMaxNum_LastPage )
				{
					ret = MemReallocMemory( ulReqSize, (VOID**)&tblMan->memoryBlocks[tblMan->block_num], &p_owner );
					if( !ret )
					{
						Throw_MemoryError( tblMan, ALLOC_REALLOCMEMORY, tblMan->maxRecordNum, 0 );
						return (FALSE);
					}
				}
				else
				{
					if( ulReqSize < tblMan->con_minPageSize  )
					{
						ulReqSize =  tblMan->con_minPageSize;
					}
					ret = MemNewMemory( ulReqSize, (VOID**)&tblMan->memoryBlocks[tblMan->block_num], &p_owner );
					if( !ret )
					{
						Throw_MemoryError( tblMan, ALLOC_NEWMEMORY, tblMan->maxRecordNum, 0 );
						return (FALSE);
					}
				}
				tblMan->astTabNum_LastPage += astTotalReq;
				tblMan->astMaxNum_LastPage = MemGetPagesize(tblMan->memoryBlocks[tblMan->block_num])/tblMan->con_usSize;
				setOwnerId_LastPage( tblMan->u4Idx , tblMan->block_num, p_owner, resetListener );
				break;
			}
			if( tblMan->block_num >= MAX_VOLUMN_OF_TABLE )
			{
				Throw_MemoryError( tblMan, ALLOC_OVERFLOW, MAX_VOLUMN_OF_TABLE, tblMan->block_num );
				return (FALSE);
			}
			astReq = tblMan->astMaxNum_Block - tblMan->astTabNum_LastPage;
			if( astReq == 0 )
			{
				tblMan->block_num++;
				tblMan->astMaxNum_LastPage = 0;
				tblMan->astTabNum_LastPage = 0;
				continue;
			}
			astTotalReq -= astReq;

			ulReqSize = blockSize;
			if( ulReqSize != 0 )
			{
				if( tblMan->astMaxNum_LastPage )
				{
					ret = MemReallocMemory( ulReqSize, (VOID**)&tblMan->memoryBlocks[tblMan->block_num], &p_owner );
					if( !ret  )
					{
						Throw_MemoryError( tblMan, ALLOC_REALLOCMEMORY, tblMan->maxRecordNum, 0 );
						return (FALSE);
					}
				}
				else
				{
					ret = MemNewMemory( ulReqSize, (VOID**)&tblMan->memoryBlocks[tblMan->block_num], &p_owner );
					if( !ret  )
					{
						Throw_MemoryError( tblMan, ALLOC_NEWMEMORY, tblMan->maxRecordNum, 0 );
						return (FALSE);
					}
				}
				if( p_owner == NULL )
				{
					Throw_MemoryError( tblMan, ALLOC_NEWMEMORY, tblMan->maxRecordNum, 0 );
					return FALSE;
				}
				setOwnerId_LastPage( tblMan->u4Idx, tblMan->block_num, p_owner, resetListener );
				tblMan->astTabNum_LastPage = tblMan->astMaxNum_Block;
				tblMan->astMaxNum_LastPage = tblMan->astMaxNum_Block;
			}
			continue;
		}
		/*_____[ 領域開放要求 ]_________________________________________*/
		else if( astTotalReq < (AST)0 )
		{
			/*  アンダーフローチェック */
			if( ( tblMan->maxRecordNum + astTotalReq ) < (AST)0 )
			{
				Throw_MemoryError( tblMan, ALLOC_UNDERFLOW, tblMan->maxRecordNum, astTotalReq );
				return (FALSE);
			}
			if( tblMan->block_num == 0 )
			{
				astReq = astTotalReq - 1;
			}
			else
			{
				astReq = astTotalReq;
			}
			if( tblMan->astTabNum_LastPage + astReq > 0 )
			{
				if( tblMan->memoryBlocks[tblMan->block_num] == NULL )
				{
					tblMan->memoryBlocks[tblMan->block_num] = MemTblSwapInTable( tblMan->u4Idx, tblMan->block_num, &p_owner );
					if( tblMan->memoryBlocks[tblMan->block_num] == NULL  )
					{
						Throw_MemoryError( tblMan, ALLOC_SWAPOUT_DATALOST, tblMan->u4Idx, tblMan->block_num );
						return (FALSE);
					}
					setOwnerId_LastPage( tblMan->u4Idx, tblMan->block_num, p_owner, resetListener );
				}
				/* 現時点のメモリ塊はまだ使われる場合*/
				/* 解放の行数を計算（すべて、1回解放する)*/
				astReq = astTotalReq;
				astTotalReq = 0;
				tblMan->astTabNum_LastPage += astReq;
				/* 減った分のﾒﾓﾘにｺﾞﾐを入れる				*/
				pStart = (char*)tblMan->memoryBlocks[tblMan->block_num] + (size_t)( tblMan->con_usSize * ( tblMan->astTabNum_LastPage ) );
				if( pStart != NULL )
				{
					memset( pStart, 0x0, (size_t)( tblMan->con_usSize * (-astReq) ) );
				}
				break;
			}
			else
			{
				/* 現時点のメモリ塊は使われなくなる場合*/
				/* 解放の行数を計算*/
				if( tblMan->block_num > 0 )
				{
					astReq = -(tblMan->astTabNum_LastPage);
					astTotalReq -= astReq;
					ret = MemFreeMemory((VOID**)&tblMan->memoryBlocks[tblMan->block_num]);
					if( !ret )
					{
						Throw_MemoryError( tblMan, ALLOC_FREEMEMORY, tblMan->block_num, 0 );
						return (FALSE);
					}
					tblMan->memoryBlocks[tblMan->block_num] = NULL;

					/* 新しいメモリ塊を配って、中間ファイルからデータを読み込む*/
					/* 保持するメモリ塊の数から１を引く */
					(tblMan->block_num) --;
					tblMan->astTabNum_LastPage = tblMan->astMaxNum_Block;
					tblMan->astMaxNum_LastPage = tblMan->astMaxNum_Block;
					setOwnerId_LastPage( tblMan->u4Idx, tblMan->block_num, &owner, resetListener );
					if( !MemIsValidPage( tblMan->memoryBlocks[tblMan->block_num], &owner ) )
					{
						tblMan->memoryBlocks[tblMan->block_num] = MemTblSwapInTable( tblMan->u4Idx, tblMan->block_num, &p_owner );
						if( tblMan->memoryBlocks[tblMan->block_num] == NULL )
						{
							Throw_MemoryError( tblMan, ALLOC_SWAPOUT_DATALOST, tblMan->u4Idx, tblMan->block_num );
							return (FALSE);
						}
						setOwnerId_LastPage( tblMan->u4Idx, tblMan->block_num, p_owner, resetListener );
					}
				}
				else
				{
					astTotalReq = 0;
					pStart = (char*)tblMan->memoryBlocks[tblMan->block_num] ;
					memset( pStart, 0x0, (size_t)( tblMan->con_usSize * (tblMan->astTabNum_LastPage) ) );
					tblMan->astTabNum_LastPage = 0;
				}
			}
		}
	}
	if( astReqArg > 0 )
	{
			while( astBlockNum < tblMan->block_num )
			{
				MemSetOldPage( tblMan->memoryBlocks[astBlockNum] );
				astBlockNum++;
			}
	}
	/*該当するテーブルの行の総数を更新する*/
	tblMan->maxRecordNum += astReqArg;
	if( tblMan->ulMaxByte < tblMan->maxRecordNum )
	{
		tblMan->ulMaxByte = tblMan->maxRecordNum;
	}
	return( 1 );
}
BOOL Clear_Com( TABLEMANAGER *man )
{
	U2 u2HeaderNo =  0;
	if( man == NULL ){
		return 1;
	}
	while( u2HeaderNo <= man->block_num )
	{
		MemFreeMemory((VOID**)&man->memoryBlocks[u2HeaderNo]);
		man->memoryBlocks[u2HeaderNo] = NULL;
		u2HeaderNo++;
	}
	man->maxRecordNum = 0;
	man->block_num = 0;
	man->astMaxNum_LastPage = (AST)0;
	man->astTabNum_LastPage = (AST)0;
	return 1;
}
BOOL Reset_Com( TABLEMANAGER *man )
{
	U2 u2HeaderNo =  0;
	if( man == NULL ){
		return 1;
	}
	while( u2HeaderNo <= man->block_num )
	{
		MemFreeMemory((VOID**)&man->memoryBlocks[u2HeaderNo]);
		man->memoryBlocks[u2HeaderNo] = NULL;
		u2HeaderNo++;
	}
	man->maxRecordNum = 0;
	man->block_num = 0;
	man->astMaxNum_LastPage = (AST)0;
	man->astTabNum_LastPage = (AST)0;
	man->ulMaxByte = 0;
	return 1;
}
/*D*/
/**************************************************************************
* 関 数 名 : copyTable
* 機    能 : 同じテーブルの行のブロックを移動する
* 引 き 数 ：
* 　　　　　　　astOrg :コピー元の開始行の連番
* 		　astDst：　コピー先の開始行の連番
*         astlenth: ブロック中の行の数
* 戻 り 値 : 成功する場合、1。失敗する場合、0
* 詳細内容 :  メモリ移動
************************************************************************/
BOOL Copy_Com( TABLEMANAGER *man, VOID (*resetListener)( U4  procid, U2 index ), AST  astOrg,  AST  astDst,  AST astLenth )
{
	/*AST lCnt;*/
	buffer_owner_info *p_owner;
	AST lSize;
	AST lHeaderNoDst;
	AST lHeaderNoOrg;
	AST lKeepDst;
	AST lKeepOrg;
	if( man->u4Idx == 0 )
	{
	    return 0;
	}
	if( astLenth < MIN_ARRAY )
	{
		return ( 1 );
	}
	/*  下限チェック */
	if( astOrg < MIN_ARRAY )
	{
		return ( 0);
	}
	if( astDst < MIN_ARRAY )
	{
		return ( 0);
	}


	/*  上限チェック */
	if( ( astOrg + astLenth - 1 ) > man->maxRecordNum )
	{
		return ( 0);
	}
	if( ( astDst + astLenth - 1 ) > man->maxRecordNum )
	{
		return ( 0);
	}

	if( astDst < astOrg )
	{
		while( astLenth > 0 )
		{
			lHeaderNoOrg = ( astOrg )/man->astMaxNum_Block;
			lHeaderNoDst = ( astDst )/man->astMaxNum_Block;

			lKeepOrg = ( astOrg )%man->astMaxNum_Block;
			lKeepDst = ( astDst )%man->astMaxNum_Block;
			lSize = astLenth;
			if( ( lKeepDst + lSize ) > man->astMaxNum_Block )
			{
				lSize = man->astMaxNum_Block - lKeepDst;
			}
			if( ( lKeepOrg + lSize ) > man->astMaxNum_Block )
			{
				lSize = man->astMaxNum_Block - lKeepOrg;
			}
			if( man->memoryBlocks[lHeaderNoDst] == NULL  )
			{
				man->memoryBlocks[lHeaderNoDst] = MemTblSwapInTable( man->u4Idx, lHeaderNoDst, &p_owner );
				if( man->memoryBlocks[lHeaderNoDst] == NULL )
				{
					return (0);
				}
				setOwnerId_LastPage( man->u4Idx, lHeaderNoDst, p_owner, resetListener );
			}
			if( man->memoryBlocks[lHeaderNoOrg] == NULL  )
			{
				man->memoryBlocks[lHeaderNoOrg] = MemTblSwapInTable( man->u4Idx, lHeaderNoOrg, &p_owner );
				if( man->memoryBlocks[lHeaderNoOrg] == NULL )
				{
					return (0);
				}
				setOwnerId_LastPage( man->u4Idx, lHeaderNoOrg, p_owner, resetListener  );
			}
			memmove(  GET_OFFSET_ADDR(man, lHeaderNoDst, lKeepDst ),
					GET_OFFSET_ADDR(man, lHeaderNoOrg, lKeepOrg ),
					(size_t)(lSize*man->con_usSize) );
			astLenth -= lSize;
			astOrg += lSize;
			astDst += lSize;
		}
	}
	else if( astDst > astOrg )
	{
		astOrg = astOrg + astLenth - 1;
		astDst = astDst + astLenth - 1;
		while( astLenth > 0 )
		{
			lHeaderNoOrg = ( astOrg )/man->astMaxNum_Block;
			lHeaderNoDst = ( astDst )/man->astMaxNum_Block;

			lKeepOrg = ( astOrg )%man->astMaxNum_Block;
			lKeepDst = ( astDst )%man->astMaxNum_Block;

			lSize = astLenth;
			if(  lSize  > (lKeepDst + 1) )
			{
				lSize = lKeepDst + 1;
			}
			if(  lSize  > (lKeepOrg + 1) )
			{
				lSize = lKeepOrg + 1;
			}
			if( man->memoryBlocks[lHeaderNoDst] == NULL  )
			{
				man->memoryBlocks[lHeaderNoDst] = MemTblSwapInTable( man->u4Idx, lHeaderNoDst, &p_owner );
				if( man->memoryBlocks[lHeaderNoDst] == NULL )
				{
					return (0);
				}
				setOwnerId_LastPage( man->u4Idx, lHeaderNoDst, p_owner, resetListener );
			}
			if( man->memoryBlocks[lHeaderNoOrg] == NULL  )
			{
				man->memoryBlocks[lHeaderNoOrg] = MemTblSwapInTable( man->u4Idx, lHeaderNoOrg, &p_owner );
				if( man->memoryBlocks[lHeaderNoOrg] == NULL )
				{
					return (0);
				}
				setOwnerId_LastPage( man->u4Idx, lHeaderNoOrg, p_owner, resetListener  );
			}

			memmove(  GET_OFFSET_ADDR(man, lHeaderNoDst, lKeepDst + 1 - lSize  ),
					GET_OFFSET_ADDR(man, lHeaderNoOrg, lKeepOrg + 1 - lSize ),
					(size_t)(lSize*man->con_usSize) );
			astLenth-=lSize;
			astOrg -= lSize;
			astDst -= lSize;
		}
	}


	return (1);
}
VOID TblClear_Terminate( VOID )
{
	CatchMemError();
	stCcConstStringAccess.reset();
	stCcLabelStrAccess.reset();
	stCppLabelStrAccess.reset();
	stCppReadBufferAccess.reset();
	stCoreLabelStrAccess.reset();
	stCoreDirectiveInfoAccess.reset();
	stCoreOptAccess.reset();
	stBlockNestAccess.reset();
	stCCDefSymChainAccess.reset();
	stCCLoopSwitchStackAccess.reset();
	stObjectMapOfTypeAccess.reset();
	stCoreCodeScpAccess.reset();
	stCoreDefRepInfoAccess.reset();
	stCppDirectiveIFGroupAccess.reset();
	stCppDisableMacroAccess.reset();
	stCppNestFileInfoAccess.reset();
	stCppIncDirAccess.reset();
	stCppMacroCtrlAccess.reset();
	stCoreMacroDefInfoAccess.reset();
	stCppMcrArgInfoAccess.reset();
	stCppMcrExtStkAccess.reset();
	stCppMcrPrmLabelAccess.reset();
	stCorePPConditionAccess.reset();
	stCppTokenAccess.reset();
	stCorePPTokenListAccess.reset();
	stDeclarationAccess.reset();
	stDeclaratorAccess.reset();
	stExpressionAccess.reset();
	stExpressionListAccess.reset();
	stCoreFileIndexAccess.reset();
	stFunctionInfoAccess.reset();
	stGblLinkageAccess.reset();
	stInitDesignationAccess.reset();
	stLexTokenAccess.reset();
	stCCLinkageAccess.reset();
	stStatementAccess.reset();
	stSymbolInfoAccess.reset();
	stCoreTranslationUnitAccess.reset();
	stTypeCmpStkAccess.reset();
	stTypeInfoAccess.reset();
	stTypeSpecifierAccess.reset();
	stUniteChainAccess.reset();
	stValueInfoAccess.reset();
	stVariableInfoAccess.reset();
}
VOID ReceiveError( MEMORY_ERROR_INFO stInfo ){
	S4  s4Ret=COEXIT_SUCCESS;
	if( stMemoryDebugInfoAccess.alloc(1)){
		AST astMax = stMemoryDebugInfoAccess.getMax();
		stMemoryDebugInfoAccess.setManager( astMax, stInfo.mnger );
		stMemoryDebugInfoAccess.lineno.set( astMax, stInfo.lineno );
		stMemoryDebugInfoAccess.code.set( astMax, stInfo.errCode );
		stMemoryDebugInfoAccess.max.set( astMax, stInfo.astMax );
		stMemoryDebugInfoAccess.idx.set( astMax, stInfo.astIdx );
	}
	switch( stInfo.errCode ){
	case ALLOC_NEWMEMORY   :
	case ALLOC_REALLOCMEMORY   :
	case ALLOC_FREEMEMORY  :
	case ALLOC_OVERFLOW   :
	case ALLOC_BUFFER_TOOLONG   :
	case ALLOC_UNDERFLOW     :
	case ALLOC_SWAPOUT_DATALOST  :
		s4Ret = COEXIT_FATAL;
		break;
	case INDEX_TOOLARGER  :
		s4Ret = COEXIT_ERROR;
		break;
	case DATA_SETTING_MISS  :
		s4Ret = COEXIT_ERROR;
		break;
	}
	Result = s4Ret > Result?s4Ret:Result;
}
S4 CatchMemError( VOID ){
	AST astMax = stMemoryDebugInfoAccess.getMax();
	AST astCnt = MIN_ARRAY;
	ALERT_MSG_PARAM   msgParam[10];
	U2 code = 0;
	while( astCnt <= astMax ){
		stErrorCode.errCode = stMemoryDebugInfoAccess.code.get( astCnt );
		stErrorCode.astIdx = stMemoryDebugInfoAccess.idx.get( astCnt );
		stErrorCode.astMax = stMemoryDebugInfoAccess.max.get( astCnt );
		stErrorCode.lineno = stMemoryDebugInfoAccess.lineno.get( astCnt );
		stErrorCode.mnger = stMemoryDebugInfoAccess.getManager( astCnt );
		switch( stErrorCode.errCode ){
		case ALLOC_NEWMEMORY   :
			code = TABLE_NEW_MEM;
			break;
		case ALLOC_REALLOCMEMORY   :
			code = TABLE_REALLOC_MEM;
			break;
		case ALLOC_FREEMEMORY  :
			code = TABLE_FREE_MEM;
			break;
		case ALLOC_OVERFLOW   :
			if( stErrorCode.mnger->con_usSize == 1 ){
				code = BUFFER_ALLOC_OVERFLOW;
			}else{
				code = TABLE_ALLOC_OVERFLOW;
			}
			break;
		case ALLOC_BUFFER_TOOLONG   :
			code = BUFFER_ALLOC_OVERFLOW;
			break;
		case ALLOC_UNDERFLOW     :
			if( stErrorCode.mnger->con_usSize == 1 ){
				code = BUFFER_ALLOC_UNDERFLOW;
			}else{
				code = TABLE_ALLOC_UNDERFLOW;
			}
			break;
		case ALLOC_SWAPOUT_DATALOST  :
			code = TABLE_DATA_LOST;
			break;
		case INDEX_TOOLARGER  :
			code = TABLE_LARGER_INDEX;
			break;
		case DATA_SETTING_MISS  :
			code = TABLE_DATA_MISTAKE;
			break;
		}
		msgParam[0].opt = "name";
		msgParam[0].param = stErrorCode.mnger->con_pszName;
		msgParam[0].next = 0;
		CCoreThrowWarning( code, 0, stErrorCode.mnger->con_pszName, msgParam );
		astCnt++;
	}
	stMemoryDebugInfoAccess.clear();
	return Result;
}

